<template>
  <div class="custom-quality-engineering-container page-common-layout">
    <div class="table-container">
      <div class="header" header="项目申请">
        <div>
          <a-button
            @click="gotoAdd()"
            class="cu-btn-primary margin-bottom-xs"
            icon="plus"
            v-action:sqstb_add
          >
            新增
          </a-button>
        </div>
      </div>
      <div class="main">
        <vxe-table
          ref="xTable"
          height="99%"
          align="center"
          show-overflow
          show-header-overflow
          border="inner"
          :data="tableData"
          :column-config="{ resizable: true }"
          size="small"
          :loading="loading"
        >
          <vxe-column type="seq" width="80" title="序号"></vxe-column>
          <vxe-column field="proName" title="项目名称"> </vxe-column>
          <vxe-column field="creator" title="创建人"> </vxe-column>
          <vxe-column field="createTime" title="创建时间"> </vxe-column>
          <vxe-column title="状态">
            <template #default="{ row }">
              <div class="status">
                <div :class="[checkStatusClass(row), 'status-icon']"></div>
                <div class="status-name">{{ checkStatusName(row) }}</div>
              </div>
            </template>
          </vxe-column>
          <vxe-column field="userName" title="当前编辑人"> </vxe-column>
          <vxe-column
            field="operate"
            width="220"
            title="操作"
            fixed="right"
            align="left"
          >
            <template #default="{ row }">
              <div class="text-button-group">
                <a-button
                  type="link"
                  v-for="(item, index) in row.normalBtns"
                  :key="index"
                  @click="eventDispacth(item.event, row)"
                  :class="[item.label == '删除' && 'danger']"
                >
                  {{ item.label }}
                </a-button>
                <a-popover
                  v-if="row.popoverBtns.length > 0"
                  overlayClassName="table-more-btns-popover"
                  placement="bottom"
                  :getPopupContainer="() => $el"
                >
                  <template slot="content">
                    <div
                      class="popover-btn"
                      v-for="(popBtn, index) in row.popoverBtns"
                      :key="index"
                      @click="eventDispacth(popBtn.event, row)"
                    >
                      {{ popBtn.label }}
                    </div>
                  </template>
                  <a-button type="link">...</a-button>
                </a-popover>
              </div>
            </template>
          </vxe-column>
        </vxe-table>
      </div>
      <div class="pager-container">
        <vxe-pager
          size="small"
          background
          :current-page.sync="pager.page"
          :page-size.sync="pager.pageSize"
          :total="pager.total"
          :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'Sizes']"
          :page-sizes="[20, 50, 100, 500]"
          @page-change="paginationChange"
        >
          <template #left>
            <div class="vxe-pager-left-tip-container">
              共<span>{{ pager.total }}</span
              >条
            </div>
          </template>
        </vxe-pager>
      </div>
    </div>
    <!-- 新增页面 -->
    <addModal
      v-if="addModalVisible"
      :visible.sync="addModalVisible"
      :rows="rows"
      @ok="handelOk()"
      @cancel="handelCancel()"
    ></addModal>
  </div>
</template>

<script>
import { Base64 } from "js-base64";
import {
  getProjectApproveList,
  deleteProjectApprove,
  updateProApproveStatus,
  reportDownLoad,
} from "@/api/qualityEngineering";
import addModal from "./components/addModal";
import { baseUrl, websocket, reportPreviewUrl } from "@/services/baseUrl";
import { downLoadWordFileByArraybuffer } from "@/utils/util";
export default {
  components: {
    addModal,
  },
  data() {
    return {
      loading: false,
      tableData: [],
      pager: {
        page: 1,
        pageSize: 20,
        total: 0,
      },
      addModalVisible: false,
      rows: {},
      wsInstance: null,
    };
  },
  mounted() {
    this.getTableData();
    this.closeSocket();
    this.connectSocket();
  },
  methods: {
    gotoAdd() {
      this.rows = { title: "新增" };
      this.addModalVisible = true;
    },
    handelOk() {
      this.addModalVisible = false;
      this.getTableData();
    },
    handelCancel() {
      this.addModalVisible = false;
      this.getTableData();
    },
    //查看
    gotoView(row) {
      this.rows = { title: "查看", ...row };
      this.addModalVisible = true;
    },
    //编辑
    editorClick(row) {
      this.rows = { title: "编辑", ...row };
      this.addModalVisible = true;
      this.updateStatus(1);
    },
    //更新状态
    updateStatus(status = 0) {
      return new Promise((resolve, reject) => {
        updateProApproveStatus({
          proUuid: this.rows.proUuid,
          uuid: this.rows.uuid,
          status,
        })
          .then((res) => {
            resolve();
          })
          .catch((_) => {
            reject();
          });
      });
    },

    //删除
    handleDelClick(row) {
      let dataLength = this.tableData.length;
      let that = this;
      that.$confirm({
        title: "提示",
        content: "确定删除该数据吗？删除之后不可恢复！",
        okText: "确定",
        cancelText: "取消",
        icon: () =>
          that.$createElement("a-icon", {
            props: {
              key: "warning",
              type: "exclamation-circle",
              twoToneColor: "#faad14",
            },
          }),
        onOk() {
          deleteProjectApprove({ uuid: row.uuid })
            .then((res) => {
              if (res.statusCode === 200 || res === 1) {
                that.$message.success("删除成功", 1.5);
                if (dataLength == 1 && that.pager.page > 1) {
                  that.pager.page -= 1;
                }
                that.getTableData();
              } else {
                that.$message.error(res.message);
              }
            })
            .catch((_) => {});
        },
      });
    },

    //下载
    downloadFile(row) {
      return new Promise((resolve, reject) => {
        reportDownLoad({ uuid: row.uuid })
          .then((res) => {
            downLoadWordFileByArraybuffer(res, row.proName);
            resolve();
          })
          .catch((_) => {
            reject();
          });
      });
    },

    //预览报告
    previewFile(row) {
      let url = `${baseUrl}/probusiness/api/apiCommon/reportPreview?uuid=${
        row.uuid
      }&fullfilename=${encodeURIComponent(row.proName)}.pdf`;
      let path =
        reportPreviewUrl +
        "/onlinePreview?url=" +
        encodeURIComponent(Base64.encode(url));
      window.open(path);
    },

    //查询列表数据
    getTableData() {
      this.loading = true;
      let { page, pageSize } = this.pager;
      getProjectApproveList({ page, pageSize })
        .then((res) => {
          this.tableData = res?.rows ?? [];
          this.pager.total = res?.totalCount ?? 0;
          this.tableData.forEach((v) => {
            this.$set(v, "userName", "-");
            this.$set(v, "download", true);
            this.$set(v, "edit", true);
            this.$set(v, "delete", true);
            let { normal = [], popover = [] } = this.filterTableButtons(v);
            v.normalBtns = normal;
            v.popoverBtns = popover;
          });
        })
        .catch((_) => {
          this.tableData = [];
          this.pager.total = 0;
        })
        .finally((_) => {
          this.loading = false;
        });
    },

    //监听分页切换
    paginationChange({ currentPage, pageSize }) {
      this.pager.page = currentPage;
      this.pager.pageSize = pageSize;
      this.getTableData();
    },

    //事件派发
    eventDispacth(eventName, params = {}) {
      if (!eventName) {
        return;
      }
      this[eventName](params);
    },

    //校验下发按钮是否展示
    filterTableButtons(row) {
      // 处理
      let buttons = [
        { label: "查看", event: "gotoView" },
        { label: "预览", event: "previewFile" },
      ];
      let result = {};
      let emuSource = {
        download: [{ label: "下载", event: "downloadFile" }],
        edit: [{ label: "编辑", event: "editorClick" }],
        delete: [{ label: "删除", event: "handleDelClick" }],
      };
      Object.keys(emuSource).forEach((key) => {
        if (row[key] == true) {
          buttons = buttons.concat(emuSource[key]);
        }
      });
      if (buttons.length > 3) {
        const middle = 2;
        result = {
          normal: buttons.slice(0, middle),
          popover: buttons.slice(middle, buttons.length),
        };
      } else {
        result = {
          normal: buttons,
          popover: [],
        };
      }
      return result;
    },

    //关闭websocket
    closeSocket() {
      this.wsInstance && this.wsInstance.close();
      this.wsInstance = null;
    },
    //连接websocket
    connectSocket() {
      this.wsInstance = new WebSocket(
        `${websocket}/probusiness/api/webSocket/qeProjectApprove`
      );
      //socket连接成功回调
      this.wsInstance.onopen = () => {
        // this.wsInstance.send();
        // console.log("Socket连接成功---------------->>>>>>");
      };

      //接受服务端发送的数据
      this.wsInstance.onmessage = (msg) => {
        // console.log(msg, "接受服务端发送的数据");
        if (this.isJsonString(msg?.data)) {
          //   console.log(JSON.parse(msg?.data ?? "{}"), "接受服务端发送的数据");
          let item = JSON.parse(msg?.data ?? "{}");
          this.tableData.forEach((v) => {
            if (v.uuid == item.uuid) {
              v.status = item.status;
              v.userName = item.userName;
              if (item.status == 1) {
                v.edit = false;
              }
              if (item.status == 0) {
                v.edit = true;
              }
              let { normal = [], popover = [] } = this.filterTableButtons(v);
              v.normalBtns = normal;
              v.popoverBtns = popover;
            }
          });
        }
      };

      //socket连接关闭时回调
      this.wsInstance.onclose = () => {
        // console.log("Socket已被关闭---------------->>>>>>");
        this.connectSocket();
      };

      //socket连接错误时回调
      this.wsInstance.onerror = (err) => {
        // console.log("Socket连接错误---------------->>>>>>");
      };
    },

    isJsonString(str) {
      try {
        JSON.parse(str);
        return true;
      } catch (e) {
        return false;
      }
    },

    //校验状态名称
    checkStatusName(row) {
      let { status } = row;
      switch (status) {
        case 0:
          return "可编辑";

        case 1:
          return "正在编辑";

        default:
          return "--";
      }
    },

    //校验状态className
    checkStatusClass(row) {
      let { status } = row;
      switch (status) {
        case 0:
          return "warn";

        case 1:
          return "normal";

        default:
          return "";
      }
    },
  },
  destroyed() {
    let { uuid } = this.rows;
    uuid && this.updateStatus(0);
  },
};
</script>

<style lang="less" scoped>
@primary-color: @primary-color;
.table-container {
  .status {
    display: flex;
    align-items: center;
    justify-content: center;
    .status-icon {
      margin-right: 4px;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      flex-shrink: 0;
      background: #aab0bc;
      &.warn {
        background: #f07f17;
      }
      &.normal {
        background: #239b53;
      }
    }
    .status-name {
      min-width: 60px;
    }
  }
}
/deep/.ant-popover {
  &.table-more-btns-popover {
    .ant-popover-inner-content {
      cursor: pointer;
      text-align: center;
      padding: 10px 0;
      .popover-btn {
        height: 30px;
        padding: 0 20px;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        margin-bottom: 10px;
        color: #525a5d;
        &:last-child {
          margin: 0;
        }
        &:hover {
          background: #e9ecf3;
          color: @primary-color;
        }
      }
    }
  }
}
</style>
